

===============================================================================

double GetJointProb_bn (const nodelist_bn *nodes, const state_bn *states);

This returns the joint probability that each of _nodes_ is in the
corresponding state of _states_, given the findings currently entered in
the belief net.  The _states_ array must provide a state for each node 
of _nodes_.

All of _nodes_ must come from the same belief net.
None of _nodes_ should have a likelihood finding.

This function is designed to work fast when retrieving many joint
probabilities from nodes that were put in the same clique during
network compilation.  The first time it is called it will take longer
to return, but on subsequent calls it will return very fast if these
these conditions are met:

1. _nodes_ is the same list for each call.
2. No calls to it with a different _nodes_ list were made in between.
3. No new findings have been entered or retracted.
4. No change was made to the network requiring re-compilation.
5. Each of _nodes_ were placed in the same clique during compiling.

If conditions 1 or 2 are violated, it will still be much faster than 
doing a new belief updating, but not as fast as if they aren't violated.
If the other conditions are violated, then it will take the same time
as 1 or 2 belief updatings.

You can be sure a set of nodes will be placed in the same clique if
there is some "family" in the belief net which contains all of them.
A _family_ consists of a node and its parents.  There is a function 
in NeticaEx.c which can be used to ensure that all of _nodes_ will be 
put in the same clique during the next compile:

node_bn *FormCliqueWith (const nodelist_bn *nodes);

Versions 1.18 and later of Netica API have the GetJointProb_bn function.

===============================================================================

MostProbableConfig_bn

void MostProbableConfig_bn (const nodelist_bn *nodes, state_bn *config,int nth);

Finds the most probable configuration, also know as the most probable
explanation (MPE) for all the nodes in the network.
This is the setting for each of the nodes with the highest overall joint 
probability, given the currently entered findings.  Of course it is consistent 
with the findings. 

For _nodes_, you must pass a list returned by GetNetNodes_bn.
Pass 0 for _nth_.  It is only for future expansion.
For _config_, pass an array of state_bn at least as long as _nodes_.
The initial contents of this array will be ignored.
Netica will fill the _config_ array with the configuration of highest joint 
probability given the currently entered findings.
Each element of _config_ is the state for the corresponding node of _nodes_
(i.e. they are in the same order, and have the same length).

The network must be compiled before calling this function.

After finding the most probable configuration, you can use GetJointProb_bn 
to find its probability (see example below).

You can mix calls to this function with calls to GetNodeBeliefs_bn 
(which finds posterior probabilities).

This function does not work when likelihood findings are entered.
In that case you must make child nodes corresponging to the observations,
whose CPTs are the likelihoods, and enter a positive finding for them.

If you must have the MPE of a smaller set of nodes than all the nodes in the
network, you can use AbsorbNodes_bn to remove the other nodes first.

Versions 1.07 and later of Netica API have this function.

Example usage:

   CompileNet_bn (net);
   const nodelist_bn* allnodes = GetNetNodes_bn (net);
   int num_nodes = LengthNodeList_bn (allnodes);
   state_bn* config = new state_bn [num_nodes];
   MostProbableConfig_bn (allnodes, config, 0);
   double maxprob = GetJointProb_bn (allnodes, config);

===============================================================================

GetNodeCenter_bn

void GetNodeCenter_bn (node_bn* node, void* vis, int* x, int* y);

Sets *_x_,*_y_ to the coordinates of the center of _node_,
as it would appear in a visual display (e.g. in Netica Application).
Pass NULL for _vis_; it is only for future expansion.

Versions 1.15 and later of Netica API have this function.

See also:
  SetNodeCenter_bn.

===============================================================================

SetNodeCenter_bn

void SetNodeCenter_bn (node_bn* node, void* vis, int x, int y);

Moves _node_ so that its center is at coordinates (_x_,_y_),
for any visual display (e.g. in Netica Application).
Pass NULL for _vis_; it is only for future expansion.

Versions 1.15 and later of Netica API have this function.

See also:
  GetNodeCenter_bn.

===============================================================================

MapStateList_bn

void MapStateList_bn (const state_bn* src_states, const nodelist_bn* src_nodes,
                      state_bn* dest_states, const nodelist_bn* dest_nodes);

Puts into the _dest_states_ array the same states that are in the
  _src_states_ array, except in a different order.
The order of _src_states_ is given by _src_nodes_, and the order of dest_states
  will be given by _dest_nodes_.
dest_nodes *must* contain exactly the same nodes as src_nodes, but possibly 
  in a different order.

Versions 1.18 and later of Netica API have this function.

Equivalent to the below, but more efficient:

#include <assert.h>
 
void MapStateList_bn (const state_bn *src_states,const nodelist_bn *src_nodes,
                       state_bn *dest_states, const nodelist_bn *dest_nodes){
   int nn, num_nodes = LengthNodeList_bn (src_nodes);
   for (nn = 0;  nn < num_nodes;  nn++)
      SetNodeUserData_bn (NthNode_bn (src_nodes, nn), 0, 
                          (void*) &src_states[nn]);
   for (nn = 0;  nn < num_nodes;  nn++){
      void *data = GetNodeUserData_bn (NthNode_bn (dest_nodes, nn), 0);
      assert (data != NULL);
      dest_states[nn] = * (state_bn *) data;
   }
}

===============================================================================

SetNodeEquation_bn

void SetNodeEquation_bn (node_bn* node, const char* eqn);

This associates the equation _eqn_ (a null terminated C character string)
as the equation of _node_.

See the onscreen help of Netica Application for information on the syntax
of Netica equations.

To remove a node's equations, pass NULL or the empty string for _eqn_.

Netica will make a copy of _eqn_; it won't modify or free the passed string.

There is no restriction on the length of the equation.

Versions 1.30 and later of Netica API have this function.

See also:
   GetNodeEquation_bn
   EquationToTable_bn

===============================================================================

GetNodeEquation_bn

const char* GetNodeEquation_bn (const node_bn* node);

Returns a (nonmodifiable) null terminated C character string which contains 
the equation associated with _node_, or the empty string (rather than NULL), 
if _node_ does not have an equation.

Do not try to modify or free the string returned.

Versions 1.30 and later of Netica API have this function.

See also:
   SetNodeEquation_bn
   EquationToTable_bn

===============================================================================

EquationToTable_bn

void EquationToTable_bn (node_bn* node, int num_samples, bool_ns samp_unc, 
                         bool_ns add_exist);

Builds the CPT for _node_ based on the equation that has been associated
with it (see SetNodeEquationText_bn).

_num_samples_ is the number of samples to make per parent condition.
The higher the number, the more accurate the conversion will be, but the
longer it will take.  If _node_ and its parents are discrete, then it only
takes one sample to generate an exact probability, and so in that case 
this argument is ignored.

_samp_unc_ indicates whether to include in the generated probability table
the uncertainty due to the sampling process or not.  If the equations are 
simple (don't have narrow spikes), and the value passed for num_samples 
is high enough, it is better to make this argument FALSE, so that the 
CPT entries for 'impossible' are zero, rather than close to zero.
Otherwise make it TRUE.

Normally you pass FALSE for _add_exist_, but you can pass TRUE if you wish the
new sampling to be added to the table which already exists.  If the equation
conversion to table is nondeterministic (i.e. requires sampling), then calling
this function twice with add_exist = TRUE is equivalent to calling it once
with a value of _num_samples_ twice as large.  So you can increase the
accuracy of the conversion in small steps by repeatedly calling with
_add_exist_ = TRUE.  Or if you want to blend equations (say you want to
indicate a 30% chance of equation 1 and a 70% chance of equation 2),
you can call it twice, first setting equation 1 and using _num_samples_ = 3,
then setting equation 2 and using _num_samples_ = 7.  Similarily, you can
blend equations with learned probabilities (see CaseFileRevisesProbs_bn),
and those entered manually with SetNodeProbs_bn and SetNodeExperience_bn.

Versions 1.18 and later of Netica API have this function.

See also:
   SetNodeEquationText_bn
   GetNodeEquationText_bn

===============================================================================

GetNodeValueEntered_bn

double GetNodeValueEntered_bn (const node_bn* node);

Returns the real-valued finding entered for _node_, or UNDEF_DBL if none has
been entered since the last retraction.

If _node_ is not a continuous node, but has been given a levels list,
and a discrete finding has been entered, then that finding will be converted
to a real-value by the levels list, and returned (see SetNodeLevels_bn
for an explanation of the levels list).

If _node_ is not a continous node, and doesn't have a levels list defined,
then an error is generated.

In versions of Netica API previous to 1.18, this function was called 
GetNodeValue_bn.

See Also:
GetNodeFinding_bn      For discrete findings
GetNodeCalcValue_bn    Will compute from neighbors if deterministic

===============================================================================

GetNodeCalcValue_bn

double GetNodeCalcValue_bn (node_bn* node);

Returns the real-valued finding entered for _node_ if one has been entered, 
or the real value calculated from its neighbors if that can be done 
deterministically, or else UNDEF_DBL.

If _node_ is not a continous node, and doesn't have a levels list defined,
then an error is generated (see SetNodeLevels_bn for an explanation of the 
levels list).

Versions 1.18 and later of Netica API have this function.

See Also:
GetNodeCalcState_bn      For discrete nodes
GetNodeValueEntered_bn   Doesn't do deterministic propagation

===============================================================================

GetNodeCalcState_bn

state_bn GetNodeCalcState_bn (node_bn* bnd);

Returns the discrete finding entered for _node_ if one has been entered, 
or the state calculated from its neighbors if that can be done 
deterministically, or else UNDEF_STATE.

If _node_ is not a discrete node, and doesn't have a levels list defined,
then an error is generated (see SetNodeLevels_bn for an explanation of the 
levels list).

Versions 1.18 and later of Netica API have this function.

See Also:
GetNodeCalcValue_bn      For real values
GetNodeFinding_bn        Doesn't do deterministic propagation

===============================================================================

SetCaseFileDelimChar_ns

int SetCaseFileDelimChar_ns (int newchar, environ_ns* env);

Sets the symbol used to separate data fields in a case file being created by
Netica.

_newchar_ must be one of tab, space or comma.

Whole cases are always separated by line ends (i.e. carriage return, newline,
or a combination of these).

_newchar_ will only be used for writing case files; while reading them Netica
will understand any of the choices.

It returns the old symbol being used for this purpose.

Versions 1.18 and later of Netica API have this function.

See also:
   SetCaseFileMissingChar_ns
   WriteCase_bn

===============================================================================

SetMissingDataChar_ns

int SetMissingDataChar_ns (int newchar, environ_ns* env);

Sets the symbol to be used for indicating missing data fields in a case file
created by Netica.

_newchar_ must be one of *, ?, space or absent (0).  It cannot by space or 
absent unless the delimeter symbol is a comma (see SetCaseFileDelimChar_ns).

It returns the old symbol being used for this purpose.

_newchar_ will only be used for writing case files; while reading them Netica
will understand any of the choices.

Versions 1.18 and later of Netica API have this function.

See also:
   SetCaseFileDelimChar_ns
   WriteCase_bn

===============================================================================

Testing a network

test_bn* CreateNetTester_bn (const nodelist_bn* test_nodes, const nodelist_bn* unobsv_nodes, int tests);
void TestWithFile_bn (test_bn* test, stream_ns* file);
double GetTestConfusion_bn (const test_bn* test, const node_bn* node, state_bn predicted, state_bn actual);
double GetTestErrorRate_bn (const test_bn* test, const node_bn* node);
double GetTestLogLoss_bn (const test_bn* test, const node_bn* node);
double GetTestQuadraticLoss_bn (const test_bn* test, const node_bn* node);
void DeleteNetTester_bn (test_bn* test);

First call CreateNetTester_bn to make a test_bn, then use that in one or more
calls to TestWithFile_bn.  At any time you can use the GetTest... functions
to retrieve their current values.  When done with the test_bn, free it with
DeleteNetTester_bn.

This function is only available in versions 1.18 and later of Netica.

===============================================================================

GetNodeExpectedUtils_bn

const util_bn* GetNodeExpectedUtils_bn (node_bn* node);

Decision networks can now have multiple utility nodes, dont need 
no-forgetting links, can be compiled, can have findings directly 
entered, etc.  Instead of using OptimizeDecisions_bn, you just
call GetNodeExpectedUtils_bn, which works like GetNodeBeliefs_bn,
except on DECISION_NODEs instead of NATURE_NODEs.
Contact Norsys for more details.

Versions 1.07 and later of Netica API have this function.

See "Decisions.txt"

===============================================================================

RandomCase_bn

int RandomCase_bn (const nodelist_bn *nodes, int method, double num)

Now takes a method argument of 0, 1, or 2.

If _method_ is 2, then forward sampling is used.  This evaluates equations 
directly if they are available, rather than just using CPT entries (which 
may just approximate the equation).  However, it uses a rejections method,
so it may be slow if the findings currently entered are improbable.

If method is 1, then the network must be compiled, and the junction
tree is used to do very fast sampling with no rejections (i.e. findings
don't slow it down).

If method is 0 (the recommended value), then the default method is used.
Currently this is method 2 if rejections won't be a problem or the network
is uncompiled, otherwise method 1.

RandomCase_bn in Netica API versions previous to 1.07 always used forward 
sampling.

===============================================================================

ErrorCategory_ns

bool_ns ErrorCategory_ns (errcondn_ns errcnd, const report_ns *error);

This is to discover the reason behind an error which has occured.
It groups together errors into broad classes.

For _errcnd_ pass a possible condition that could have been
the reason for the error, and it returns TRUE if that indeed was the
reason.

These are the possible values for _errcnd_:

   OUT_OF_MEMORY_CND    System did not have enough memory to complete operation
   INCONS_FINDING_CND   Inconsistent finding (only)
   USER_ABORTED_CND     User halted command before finishing (not possible when
                        using a Netica API version without the user interface)
   FROM_DEVELOPER_CND   Created by your program using ReportError_ns
                        

Versions 1.30 and later of Netica API have this function.

===============================================================================


